package model;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;

public class MoviesInfosFinder {

	/**.
	 * HTTP client
	 */
	private static DefaultHttpClient httpClient;
	/**.
	 * HTTP get request
	 */
	private static HttpGet getRequest;
	/**.
	 * HTTP response
	 */
	private static HttpResponse response;
	/**.
	 * buffered reader
	 */
	private static BufferedReader reader;
	/**.
	 * output
	 */
	private static String output;
	/**.
	 * JSON factory
	 */
	private static JsonFactory jFactory;
	/**.
	 * JSON parser
	 */
	private static JsonParser parser;

	/**.
	 * Get informations of all the movies from the omdb API
	 * @return the movie list
	 */
	public static MoviesList getMoviesInfos(MoviesList moviesList) {
		httpClient = new DefaultHttpClient();
		for (int i = 0; i < moviesList.getMovies().size() ; i++) {
			getRequest = new HttpGet("http://www.omdbapi.com/?t="+moviesList.getMovies().get(i).getSearch()+"&tomatoes=true");
			getRequest.addHeader("accept", "application/json");
			try {
				response = httpClient.execute(getRequest);
				
				if (response.getStatusLine().getStatusCode() != 200) {
					throw new RuntimeException("Failed : HTTP error code : "+ response.getStatusLine().getStatusCode());
				}
		 
				reader = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));
				output = reader.readLine();
				
				moviesList=parseJSON(moviesList,i);
					
			} catch (ClientProtocolException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		httpClient.getConnectionManager().shutdown();

		return moviesList;
	}

	/**.
     * This function is used to parse the json received and to complete the corresponding movie object.
	 * @param movie
	 * @return the movie list
	 */
	public static MoviesList parseJSON(final MoviesList moviesList, int i) {
		jFactory = new JsonFactory();

		try {
			parser = jFactory.createJsonParser(output);

			while (parser.nextToken() != JsonToken.END_OBJECT) {
				String fieldname = parser.getCurrentName();

				if ("Title".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setTitle(parser.getText());
				}
				if ("Year".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setYear(Integer.parseInt(parser.getText()));
					moviesList.getMovies().get(i).setCompleted(true);
				}
				if ("Rated".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setClassification(parser.getText());
				}
				if ("Released".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).getRelease().setTheatre(parser.getText());
				}
				if ("Runtime".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setRuntime(parser.getText());
				}
				if ("Genre".equals(fieldname)) {
					parser.nextToken();
					String[] str = parser.getText().split("\\,");
					for (int j = 0; j < str.length; j++) {
						moviesList.getMovies().get(i).addGenre(str[j].replaceAll("^\\s+", ""));
					}
				}
				if ("Director".equals(fieldname)) {
					parser.nextToken();
					String[] str = parser.getText().split("\\,");
					for (int j = 0; j < str.length; j++) {
						moviesList.getMovies().get(i).addDirector(str[j].replaceAll("^\\s+", ""));
					}
				}
				if ("Writer".equals(fieldname)) {
					parser.nextToken();
					String[] str = parser.getText().split("\\,");
					for(int j = 0; j < str.length; j++) {
						moviesList.getMovies().get(i).addWriter(str[j].replaceAll("^\\s+", ""));
					}
				}
				if ("Actors".equals(fieldname)) {
					parser.nextToken();
					String[] str = parser.getText().split("\\,");
					for(int j = 0; j < str.length; j++) {
						moviesList.getMovies().get(i).addActors(str[j].replaceAll("^\\s+", ""));
					}
				}
				if ("Plot".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setPlot(parser.getText());
				}
				if ("Poster".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setPoster(parser.getText());
				}
				if ("imdbRating".equals(fieldname)) {
					parser.nextToken();
					if (!parser.getText().equals("N/A")) {
						moviesList.getMovies().get(i).getRating().setImdbRating(Float.valueOf(parser.getText()));
					}
				}
				if ("tomatoMeter".equals(fieldname)) {
					parser.nextToken();
					if (!parser.getText().equals("N/A")) {
						moviesList.getMovies().get(i).getRating().setTomatoMeter(Float.valueOf(parser.getText())/10);
					}
				}
				if ("tomatoImage".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).getRating().setTomatoImage(parser.getText());
				}
				if ("tomatoConsensus".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).getRating().setCritic(parser.getText());
				}
				if ("tomatoUserMeter".equals(fieldname)) {
					parser.nextToken();
					if (!parser.getText().equals("N/A")) {
						moviesList.getMovies().get(i).getRating().setTomatoUserMeter(Float.valueOf(parser.getText())/10);
					}
				}
				if ("DVD".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).getRelease().setDvd(parser.getText());
				}
				if ("BoxOffice".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setBoxOffice(parser.getText());
				}
				if ("Production".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setProduction(parser.getText());
				}
				if ("Website".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setWebsite(parser.getText());
					if (moviesList.getMovies().get(i).getPoster().equals("N/A")) {
						moviesList.getMovies().get(i).setCompleted(false);
					} else {
						moviesList.getMovies().get(i).setCompleted(true);
					}
				}
			}

		} catch (JsonParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return moviesList;
	}

}
